package msrc

import "context"

// MultiServiceInterface описывает интерфейс сервера с множественными
// дочерними сервисами. Идея в том, чтобы запускать каждый дочерний
// сервис в отдельном потоке и реагировать на остановку каждого из них.
// Если сервис завершил работу с ошибкой, то необходимо остановить работу
// приложения, для гарантии его корректной работоспособности.
//
// Данный подход хорошо подходит для Kubernetes, который отслеживает
// не корректные остановки подов. Если POD завершил работу с ошибкой
// и он должен продолжать работать - Kubernetes перезапустит его в
// автоматическом режиме.
type MultiServiceInterface interface {
	// Run выполняет запуск основного сервиса
	Run() error

	// Stop выполняет остановку основного сервиса
	Stop()

	// IsServicesRun проверяет, запущен ли сервер
	IsServicesRun() bool

	// IsServicesAlive проверяет, остановлен ли хоть один из сервисов
	IsServicesAlive() bool
}

// ServiceInterface описывает интерфейс сервиса, для параллельного запуска.
type ServiceInterface interface {
	// Run выполняет запуск сервера
	Run() error

	// GracefulShutdown выполняет правильную остановку сервиса
	GracefulShutdown()

	// IsStarted возвращает статус состояния запуска сервиса
	IsStarted() bool

	// IsAlive возвращает статус сервиса: живой или нет
	IsAlive() bool
}

// SimpleService описывает интерфейс упрощенного сервиса, для библиотеки.
// Данный сервис может быть использован в случаях, когда нет необходимости
// внутри следить за флагами состояния. Сервис должен реализовывать лишь
// функционал работы и правильной остановки.
type SimpleService interface {
	// Run выполняет запуск упрощенной версии сервиса.
	// На вход передается контекст, который передаст `<-ctx.Done()` в случае
	// его остановки. Сам сервис должен обрабатывать его, если он не реализует
	// своего собственного, отдельного алгоритма остановки.
	Run(ctx context.Context) error

	// GracefulShutdown выполняет правильную остановку упрощенного
	// сервиса. В данном случае, если сервис необходимо останавливать
	// вызовом отдельного функционала остановки, этот метод предоставляет
	// такую возможность.
	//
	// Метод вызывается в процессе остановки сервера и принимает на вход
	// контекст с deadline, устанавливаемым сверху. За установленное время
	// сервис либо завершает работу, либо отключается принудительно.
	GracefulShutdown(ctx context.Context) error
}
